package lormi.meipin.util;

import lormi.meipin.common.Constants;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.math.BigInteger;
import java.security.MessageDigest;

/**
 * 编码工具类
 * */
public class TEncryptUtil {
	//AES编码参数
	private static final String keyAdd = "jud947ju8f7g6cj";//密钥不足16位时，补充到16位
	private static final String ivParameter = "8542365211550541";//密钥偏移量
	
	/** 
     * 将byte[]转为各种进制的字符串 
     * @param bytes byte[] 
     * @param radix 可以转换进制的范围，从Character.MIN_RADIX到Character.MAX_RADIX，超出范围后变为10进制 
     * @return 转换后的字符串 
     */  
    public static String binary(byte[] bytes, int radix){  
        return new BigInteger(1, bytes).toString(radix);// 这里的1代表正数  
    } 
	
    /** 
     * base 64 加密 
     * @param bytes 待编码的byte[] 
     * @return 编码后的base 64 code 
     */  
    public static String enBase64(byte[] bytes){  
        return new BASE64Encoder().encode(bytes);  
    }  
      
    /** 
     * base 64 解密 
     * @param base64Code 待解码的base 64 code 
     * @return 解码后的byte[] 
     * @throws Exception 
     */  
    public static byte[] deBase64(String base64Code) throws Exception{  
        return new BASE64Decoder().decodeBuffer(base64Code);  
    } 
    
    /** 
     * 获取32位的md5值
     * @param bytes byte[] 
     * @return md5 
     * @throws Exception 
     */  
    public static String md5_32(byte[] bytes) throws Exception {
        MessageDigest md = MessageDigest.getInstance("MD5");  
        md.update(bytes);
        byte b[] = md.digest();
        int i;
        StringBuffer buf = new StringBuffer();
        for (int offset = 0; offset < b.length; offset++) {
            i = b[offset];
            if (i < 0)
                i += 256;
            if (i < 16)
                buf.append("0");
            buf.append(Integer.toHexString(i));
        }
        return buf.toString();
    }

    /**
     * 获取16位的md5值
     * @param bytes byte[]
     * @return md5
     * @throws Exception
     */
    public static String md5_16(byte[] bytes) throws Exception {
        return md5_32(bytes).substring(8,24);
    }

    /** 
     * 获取字符串md5值 
     * @param msg  
     * @return md5 
     * @throws Exception 
     */
    public static String md5_32(String msg) throws Exception {
        return md5_32(msg.getBytes(Constants.defaultEncoding_UTF8));
    }
    public static String md5_16(String msg) throws Exception {
        return md5_16(msg.getBytes(Constants.defaultEncoding_UTF8));
    }

    /** 
     * 结合base64实现md5_32加密
     * @param msg 待加密字符串 
     * @return 获取md5后转为base64 
     * @throws Exception 
     */  
    public static String md5Encrypt(String msg) throws Exception{
        return enBase64(md5_32(msg).getBytes());
    }
    
    /**
	 * AES 加密 CBC（Cipher Block Chaining，加密块链）模式
	 *  byte[] content 需要加密内容
	 *  String secretkey 密钥
	 * @return byte[] 加密之后byte []
	 * */
	public static byte[] enAES(String content, String secretkey) throws Exception { 
		secretkey += keyAdd.substring(0,(16-secretkey.length()));
		System.out.println("加密："+secretkey);
		Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");// 创建密码器   
		SecretKeySpec skeySpec = new SecretKeySpec(secretkey.getBytes(), "AES");
		// 使用CBC模式，需要一个向量iv，可增加加密算法的强度
		IvParameterSpec iv = new IvParameterSpec(ivParameter.getBytes());
        cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);
		
        return cipher.doFinal(content.getBytes("UTF-8")); // 加密   
	}  
	
	/**
	 * AES 解密 CBC（Cipher Block Chaining，加密块链）模式
	 *  byte[] content 需要解密内容
	 *  String secretkey 密钥
	 * @return String 解密之后的字符串
	 * */
	public static String deAES(byte[] content, String secretkey) throws Exception { 
		secretkey += keyAdd.substring(0,(16-secretkey.length())); 
		System.out.println("解密："+secretkey);
        SecretKeySpec skeySpec = new SecretKeySpec(secretkey.getBytes("ASCII"),"AES");
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        IvParameterSpec iv = new IvParameterSpec(ivParameter.getBytes());
        cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);
        return new String(cipher.doFinal(content),"UTF-8"); 
	}
		
	public static void main(String args[]) throws Exception{
		System.out.println(TEncryptUtil.md5_32("ddddd=&"));
    }
	
}
